package com.example.activiti.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.activiti.common.cmd.ExecutionVariableDeleteCmd;
import com.example.activiti.common.cmd.FlowToFirstCmd;
import com.example.activiti.common.cmd.TaskDeleteCmd;
import com.example.activiti.common.constant.InstanceStatus;
import com.example.activiti.common.constant.PublicKeyword;
import com.example.activiti.dto.publicDto.ActivitiResponseDto;

@Service
public class ActivitiReturnService  {
	@Autowired
	private TaskService taskService;
	//activiti服务管理服务，用于管理所有的服务，常用于后台管理
	@Autowired
	private ManagementService managementService;
	@Resource
    private RuntimeService runtimeService;
	
	
	
	/**
	 * 拒绝功能（默认都回到初始化节点）
	 * 在任意节点拒绝后自动回到发起人节点，发起人重新提交后流程重新开始。
	 * 那么面临的两个问题是
	 * (1)流程图中没有发起人节点，怎么造出这个发起人节点
	 * (2)流程已经在流转中了，如何重新流转
	 * 
	 */
	public ActivitiResponseDto refuseToStart(String taskId, String assignee, String opinion) {
		ActivitiResponseDto activitiResponseDto = new ActivitiResponseDto();
		//删除所有当前task，保留一个，并且将该task的审批人设为发起人  
	    //设置reject标志  
	    Task t = taskService.createTaskQuery()  
	            .taskId(taskId)  
	            .singleResult();  
	    
	    String instanceId = t.getProcessInstanceId();  
	    List<Task> tasks = taskService.createTaskQuery()  
	            .processInstanceId(instanceId)  
	            .list();  
	    Task luckyTask = tasks.get(0);  
	    managementService.executeCommand(new ExecutionVariableDeleteCmd(t.getExecutionId()));  
	    for (int i = 1; i < tasks.size(); ++i) {  
	        managementService.executeCommand(new TaskDeleteCmd(tasks.get(i).getId()));  
	        managementService.executeCommand(new ExecutionVariableDeleteCmd(tasks.get(i).getExecutionId()));  
	    }  
	    //将发起人设置为当前审批人  
	    taskService.setAssignee(luckyTask.getId(), (String) taskService.getVariable(luckyTask.getId(), "submitter"));  
	    //设置变量标识当前状态是已拒绝状态  
	    Map<String, Object> resMap = new HashMap<String, Object>();
	    Integer status = InstanceStatus.REJECT.getStatus();
	    resMap.put(PublicKeyword.CHECKSTATUS, status);
	    resMap.put(PublicKeyword.TASKCHECKASSIGNEE, assignee);
	    resMap.put(PublicKeyword.OPINION, opinion);
	    taskService.setVariables(luckyTask.getId(), resMap);  
	    
	    //设置返回值
	    activitiResponseDto.setAssignee(t.getAssignee());
	    activitiResponseDto.setInstanceId(t.getProcessInstanceId());
	    activitiResponseDto.setProcessDefinitionId(t.getProcessDefinitionId());
	    activitiResponseDto.setCheckStatus(InstanceStatus.REJECT.getStatus());
	    activitiResponseDto.setTaskCheckAssignee(assignee);
	    activitiResponseDto.setTaskCreateDate(t.getCreateTime());
	    activitiResponseDto.setTaskId(t.getId());
	    activitiResponseDto.setTaskName(t.getName());
	    activitiResponseDto.setTaskOpinion(opinion);
	    rollbackFirstask(t.getId());
	    return activitiResponseDto;
	}
	
	
	/** 
	 * 流程回退到第一个节点 
	 * 
	 * @param context 
	 * @param request 
	 * @param user 
	 * @return 
	 */  
	public void rollbackFirstask(String taskId) {  
	    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();  
	    //删除任务  
	    managementService.executeCommand(new TaskDeleteCmd(taskId));  
	    //删除变量  
	    managementService.executeCommand(new ExecutionVariableDeleteCmd(task.getExecutionId()));  
	    //将流程回滚到第一个节点  
	    managementService.executeCommand(new FlowToFirstCmd(task));  
	}
	
	
	/**
	 * 撤回发布的流程
	 */
	public void delInstance(String instanceId, String deleteReason) {
		runtimeService.deleteProcessInstance(instanceId, deleteReason);
	}
}
